package copyengine.ui.dialog
{
	import copyengine.utils.GeneralUtils;

	import flash.display.DisplayObjectContainer;
	import flash.utils.Dictionary;

	public final class CEDialogManager
	{
		private static var _instance:CEDialogManager;

		public static function get instance():CEDialogManager
		{
			if (_instance == null)
			{
				_instance = new CEDialogManager();
			}
			return _instance;
		}

		private var dialogLayer:DisplayObjectContainer;
		private var screenDialogGroupPopVector:Vector.<CEDialogGroupPopWarp>;
		private var isDuringGroupCommand:Boolean;

		/**
		 *在GroupCommand模式下,所引用的PopWar
		 * </br><b>注意!!! </b>该值在endGroupCommand后及无意义
		 */
		private var duringGroupCommandPopWarp:CEDialogGroupPopWarp;


		/**
		 *当前是否正在执行cleanAllSceneDialog函数,
		 * 如果执行cleanAllSceneDialog函数中,及不再响应doDisposeDialogPopWarp函数,以免多次操作Vector
		 */
		private var isDuringPopWarpDispose:Boolean;


		public function CEDialogManager()
		{
		}

		public function initialize(_dialogLayer:DisplayObjectContainer):void
		{
			dialogLayer = _dialogLayer;
			screenDialogGroupPopVector = new Vector.<CEDialogGroupPopWarp>();
		}

		//=================================================//
		//==                                    Public Interface                                            ==//
		//=================================================//

		/**
		 * 弹出对话框到屏幕上
		 *
		 * @param _dialog				需要弹出的对话框
		 * @param _isModal			是否使用模态,如果为模态对话框则下方对话框无法点击
		 * @param _arg					#see CEDialogWarp
		 */
		public function popup(_dialog:CEDialog, _isModal:Boolean = true, _arg:Object = null):*
		{
			var popWarp:CEDialogGroupPopWarp = getDialogPopWarpByDialogUniqueName(_dialog.getDialogUniqueName());
			var dialogWarp:CEDialogWarp
			if (popWarp)
			{
				//如果在GroupCommand中Pop一个已经存在的Dialog,则将其从原来的PopWarp中删除,放入
				//DuringGroupCommand中new出来的PopWarp中,在EndGroupCommand时候刷新
				dialogWarp = popWarp.getDialogWarpByDialogUniqueName(_dialog.getDialogUniqueName());

				//当前场景中已经存在Dialog
				if (isDuringGroupCommand)
				{
					popWarp.removeDialogWarp(dialogWarp);
					dialogWarp.groupCommandMarkType = CEDialogWarp.GROUP_COMMAND_MARK_TYPE_ACTIVATE;
					duringGroupCommandPopWarp.addDialogWarp(dialogWarp);
				}
				else
				{
					//刷新当前PopWarp
					popWarp.show();
				}
			}
			else
			{
				//当前场景中不存在Dialog,New出新的Dialog
				dialogWarp = new CEDialogWarp(_dialog, _isModal, _arg);
				if (isDuringGroupCommand)
				{
					dialogWarp.groupCommandMarkType = CEDialogWarp.GROUP_COMMAND_MARK_TYPE_ACTIVATE;
					duringGroupCommandPopWarp.addDialogWarp(dialogWarp);
				}
				else
				{
					popWarp = new CEDialogGroupPopWarp();
					popWarp.initialize(doDisposeDialogPopWarp, dialogLayer);
					popWarp.addDialogWarp(dialogWarp);
					popWarp.show();
					screenDialogGroupPopVector.push(popWarp);
				}
			}
			return dialogWarp.targetDialog;
		}

		/**
		 *<b>清除当前场景上的所有Dialog</b>
		 * </br>该方法用于以下两种情形:
		 * <li>在beginGroupCommand&endGroupCommand中调用,此时会清除所有没有Group之中重新reactive
		 * 或者Pop出来的Dialog,比如屏幕上面本身有3个面板,此时请求开启一个新的面板,首先会清除屏幕上面其余面板,
		 * 然后再显示新的面板
		 * <li>在场景切换时候调用,此时会直接清除当前屏幕上面所有的面板
		 */
		public function cleanAllSceneDialog():void
		{
			isDuringPopWarpDispose = true;
			var popWarp:CEDialogGroupPopWarp
			if (isDuringGroupCommand)
			{
				//设置所有NONE状态下的Dialog状态为Dispose
				for each (popWarp in screenDialogGroupPopVector)
				{
					for each (var dialogWarp:CEDialogWarp in popWarp.getAllGroupPopVector())
					{
						if (dialogWarp.groupCommandMarkType == CEDialogWarp.GROUP_COMMAND_MARK_TYPE_NONE)
						{
							dialogWarp.groupCommandMarkType = CEDialogWarp.GROUP_COMMAND_MARK_TYPE_DISPOSE;
						}
					}
				}
			}
			else
			{
				for each (popWarp in screenDialogGroupPopVector)
				{
					popWarp.dispose();
				}
				screenDialogGroupPopVector.length = 0;
			}
			isDuringPopWarpDispose = false;
		}

		/**
		 * <b>判断某一个Dialog面板是否已经在场景中Pop</b>
		 * <li>上层逻辑存在需求：ADialog面板里面的逻辑需要根据是否存在B面板而改变,
		 * (比如人物背包面板,要根据当前是否打开卖出面板来确定点击以后执行的逻辑,是直接卖出该物品还是将该物品拿起)
		 */
		public function isDialogExist(_dialogUniqueName:String):Boolean
		{
			return getDialogPopWarpByDialogUniqueName(_dialogUniqueName) != null;
		}

		public function beginGroupCommand():void
		{
			if (!isDuringGroupCommand)
			{
				isDuringGroupCommand = true;
				duringGroupCommandPopWarp = new CEDialogGroupPopWarp();
				duringGroupCommandPopWarp.initialize(doDisposeDialogPopWarp, dialogLayer);

				//设置所有Dialog状态为NONE
				for each (var popWarp:CEDialogGroupPopWarp in screenDialogGroupPopVector)
				{
					for each (var dialogWarp:CEDialogWarp in popWarp.getAllGroupPopVector())
					{
						dialogWarp.groupCommandMarkType = CEDialogWarp.GROUP_COMMAND_MARK_TYPE_NONE
					}
				}
			}
		}

		public function endGroupCommand():void
		{
			if (isDuringGroupCommand)
			{
				isDuringGroupCommand = false;
				for (var j:int = screenDialogGroupPopVector.length - 1; j >= 0; j--)
				{
					//反向循环,因为该函数有可能导致PopWarpDispose
					screenDialogGroupPopVector[j].removeAllMarkGroupDisposeTypeDialogWarp();
				}
				//如果在GroupCommand中Pop了Dialog则add新的PopWarp
				if (duringGroupCommandPopWarp.getAllGroupPopVector().length > 0)
				{
					duringGroupCommandPopWarp.show();
					screenDialogGroupPopVector.push(duringGroupCommandPopWarp);
				}
				duringGroupCommandPopWarp = null;
			}
		}

		//======================================================//
		//==                                         Private Function                                                  ==//
		//======================================================//
		/**
		 * <b>尝试从当前已经Pop出来的Dialog中寻找到指定的Dialog并返回</b>
		 * </br>该方法用于以下情形:
		 * <li>当玩家点击屏幕上面的Icon->popDialog,如果没有pop过dialog则直接pop出来一个,
		 * 如果已经pop过Dialog则返回原来的Dialog,并将Dialog放在所有的Dialog的最上层且居中显示
		 */
		private function getDialogPopWarpByDialogUniqueName(_uniqueName:String):CEDialogGroupPopWarp
		{
			for each (var dialogPopWarp:CEDialogGroupPopWarp in screenDialogGroupPopVector)
			{
				if (dialogPopWarp.getDialogWarpByDialogUniqueName(_uniqueName) != null)
				{
					return dialogPopWarp;
				}
			}
			return null;
		}

		private function doDisposeDialogPopWarp(_dialogPopWarp:CEDialogGroupPopWarp):void
		{
			!isDuringPopWarpDispose && GeneralUtils.removeElementFromArrayOrVector(_dialogPopWarp, screenDialogGroupPopVector);
		}

	}
}
